﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZerAx.ObjectNotation;
using ZerAx.Tweaks;

namespace BlockOS
{
    public class BlockData : IEquatable<BlockData>
    {
        public string id;
        public Dictionary<string, Zon> metas;

        private BlockData() { }

        public BlockData(string id)
        {
            this.id = id;
            metas = new();
        }

        public BlockData(ZonCompound dom)
        {
            id = dom.GetString("id");
            metas = dom.GetCompound("meta").data;
        }

        public BlockData(string id, params (string, Zon)[] metas) : this(id)
        {
            this.metas = metas.ToDict();
        }

        public static BlockData FromZonDom(ZonCompound zon)
        {
            var id = zon["id"].As<ZonString>().data.ToString();
            var metas = new Dictionary<string, Zon>(zon["metas"].As<ZonCompound>().data);

            return new BlockData
            {
                id = id,
                metas = metas
            };
        }

        public Zon ToZon() => 
            Zon.Compound(
                ("id", id), 
                ("metas", Zon.Compound(metas))
            );

        public bool Equals(BlockData other)
        {
            if (other.id != id) return false;
            
            if (other.metas.Count != metas.Count) return false;

            foreach (var (key, val) in metas)
            {
                if (!other.metas.ContainsKey(key)) return false;
                if (other.metas[key] != val) return false;
            }

            return true;
        }

        public override bool Equals(object obj)
        {
            if (obj is BlockData d) return Equals(d);
            return false;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public static bool operator == (BlockData left, BlockData right) => left.Equals(right);
        public static bool operator != (BlockData left, BlockData right) => !left.Equals(right);
    }
}
